package cn.schoolwow.quickdao.module.entity.flow;

import cn.schoolwow.quickdao.domain.QuickDAOConfig;
import cn.schoolwow.quickdao.domain.entity.Entity;
import cn.schoolwow.quickdao.domain.entity.Property;
import cn.schoolwow.quickdao.module.entity.flow.annotation.ScanPropertyAnnotationFlow;
import cn.schoolwow.quickdao.module.entity.flow.annotation.ScanTableAnnotationFlow;
import cn.schoolwow.quickdao.module.entity.flow.scan.ScanEntityClassFlow;
import cn.schoolwow.quickdao.module.entity.flow.scan.ScanPackageClassFlow;
import cn.schoolwow.quickflow.domain.FlowContext;
import cn.schoolwow.quickflow.flow.BusinessFlow;

import java.util.Iterator;

public class SetEntityMapFlow implements BusinessFlow {
    @Override
    public void executeBusinessFlow(FlowContext flowContext) throws Exception {
        flowContext.printTrace(false);

        scanEntityMap(flowContext);
        handleDefinerEntityMap(flowContext);
        specialHandle(flowContext);
        handleEntityListener(flowContext);

        flowContext.printTrace(true);
    }

    @Override
    public String name() {
        return "设置实体类信息";
    }

    private void scanEntityMap(FlowContext flowContext){
        QuickDAOConfig quickDAOConfig = flowContext.checkInstanceData(QuickDAOConfig.class);
        //扫描实体类
        flowContext.executeFlowList(new ScanEntityClassFlow(), new ScanPackageClassFlow());
        //扫描实体类上的注解
        Iterator<Entity> entityIterator = quickDAOConfig.databaseContext.entityMap.values().iterator();
        while (entityIterator.hasNext()) {
            Entity entity = entityIterator.next();
            flowContext.putTemporaryData("entity", entity);
            flowContext.executeFlowList(new ScanPropertyAnnotationFlow(),new ScanTableAnnotationFlow());
        }
    }

    private void handleDefinerEntityMap(FlowContext flowContext){
        QuickDAOConfig quickDAOConfig = flowContext.checkInstanceData(QuickDAOConfig.class);

        for(Entity entity:quickDAOConfig.entityOption.definerEntityMap.values()){
            Entity targetEntity = quickDAOConfig.databaseContext.entityMap.get(entity.clazz.getName());
            if(null==targetEntity){
                continue;
            }
            if(null!=entity.tableName){
                targetEntity.tableName = entity.tableName;
            }
            if(null!=entity.comment){
                targetEntity.comment = entity.comment;
            }
            targetEntity.indexFieldList.addAll(entity.indexFieldList);

            for(Property property:entity.properties){
                Property targetProperty = targetEntity.getPropertyByFieldNameOrColumnName(property.name);
                if(null==targetProperty){
                    continue;
                }
                if(!property.id){
                    targetProperty.id = true;
                }
                if(null!=property.strategy){
                    targetProperty.strategy = property.strategy;
                }
                if(null!=property.columnType){
                    targetProperty.columnType = property.columnType;
                }
                if(null!=property.column){
                    targetProperty.column = property.column;
                }
                if(null!=property.comment){
                    targetProperty.comment = property.comment;
                }
                if(null!=property.notNull){
                    targetProperty.notNull = property.notNull;
                }
                if(null!=property.check){
                    targetProperty.check = property.check;
                }
                if(null!=property.defaultValue){
                    targetProperty.defaultValue = property.defaultValue;
                }
            }
        }
    }

    private void specialHandle(FlowContext flowContext){
        QuickDAOConfig quickDAOConfig = flowContext.checkInstanceData(QuickDAOConfig.class);

        //H2数据库所有字段都大写
        if ("H2".equalsIgnoreCase(quickDAOConfig.databaseContext.databaseProvider.name())) {
            for(Entity entity:quickDAOConfig.databaseContext.entityMap.values()){
                entity.tableName = entity.tableName.toUpperCase();
                for (Property property : entity.properties) {
                    property.column = property.column.toUpperCase();
                }
            }
        }
    }

    private void handleEntityListener(FlowContext flowContext){
        QuickDAOConfig quickDAOConfig = flowContext.checkInstanceData(QuickDAOConfig.class);

        if(null==quickDAOConfig.entityOption.entityListener){
            return;
        }
        for(Entity entity:quickDAOConfig.databaseContext.entityMap.values()){
            quickDAOConfig.entityOption.entityListener.afterScanEntity(entity);
        }
    }
}
